EP8. 양자화 및 할루시네이션

LLM 파라미터 정밀도를 줄여 메모리·연산 비용을 절감하는 양자화와, 확률적 토큰 생성 메커니즘에서 비롯되는 환각 현상의 원인 및 3가지 완화 전략을 다룹니다.


0. 사전 필수 용어 (선행지식)

이 섹션의 용어를 이해하면 이후 본문을 막힘 없이 읽을 수 있습니다.

  • 부동소수점 (FP32 / FP16 / FP8): 실수를 이진수로 표현하는 방식입니다. 할당 비트 수가 클수록 표현 정밀도가 높고 메모리를 더 많이 사용합니다. ## 2, ## 3에서 정밀도 선택 기준으로 등장합니다.
  • 정수 양자화 (INT8 / INT4): 실수 파라미터를 정수로 변환하는 방식입니다. 부동소수점에 비해 연산 속도가 빠르며, MPU(Neural Processing Unit) 같은 정수 전용 하드웨어에서는 필수입니다. ## 3, ## 4에서 구현 방법을 다룹니다.
  • KV 캐시 (Key-Value Cache): Transformer 추론 시 이전 토큰의 Key/Value 어텐션 값을 재사용하기 위해 메모리에 저장한 구조체입니다. 캐시 양자화(## 3)의 핵심 대상입니다.
  • Hallucination (환각): LLM이 사실과 다른 내용을 일관성 있게 생성하는 현상입니다. 모델 버그가 아니라 확률적 토큰 생성 구조의 자연스러운 결과입니다. ## 6, ## 7에서 원인과 완화 전략을 다룹니다.
  • Top-p / Temperature: 다음 토큰을 샘플링할 때 확률 분포를 조절하는 파라미터입니다. 낮은 temperature는 더 결정적인(greedy) 출력을 만들며 환각 완화에 활용합니다. ## 7에서 인퍼런스 제어 전략으로 등장합니다.

📚 참고: 선행 개념이 필요하다면 HuggingFace NLP Course Ch.1을 먼저 학습하세요.


1. 주제 정의

양자화(Quantization)는 모델 파라미터나 연산 중간값의 수치 정밀도(비트 수)를 낮춰 메모리 사용량과 연산량을 줄이는 기법입니다. 환각(Hallucination)은 LLM이 확률에 따라 토큰을 순차적으로 생성하는 구조적 특성으로 인해, 사실 여부와 무관하게 일관성 있는 텍스트를 만들어내는 현상입니다.

핵심 아이디어: 양자화는 "정밀도 손실 대비 품질 손실이 훨씬 적다"는 경험적 발견에 기반하고, 환각은 "LLM은 진리가 아닌 확률로 작동한다"는 구조적 사실에서 비롯됩니다.


2. 풀려는 문제

  • 문제 1 (메모리 비용): 7B 모델 FP16 기준 약 14GB VRAM이 필요합니다. 수십억 파라미터 모두 2바이트로 저장하면 컨슈머 GPU에서 로드 불가합니다.
  • 문제 2 (추론 latency): 부동소수점 연산은 정수 연산보다 느립니다. 특히 엣지 디바이스(MPU, NPU) 환경에서 실수 연산 자체가 불가하거나 극히 비효율적입니다.
  • 문제 3 (온디바이스 요구사항): AI PC, 코파일럿 PC 내 MPU는 정수 기반 모델만 구동 가능합니다. 정수 양자화 없이는 NPU 가속이 불가합니다.
  • 문제 4 (환각 신뢰성): 사용자는 LLM 출력을 사실로 받아들이지만, 모델은 통계적 일관성을 목표로 생성하므로 사실 오류가 자연 발생합니다.

💡 실무 노하우: 양자화는 항상 모델 품질 손실을 동반합니다. FP16 → FP8/INT8까지는 품질 저하가 미미하지만, INT4부터는 도메인별 정밀 평가가 필수입니다. 상용 서비스는 양자화를 적용하지 않는 경우가 대부분이며, 온디바이스·개발·연구 환경에서 주로 활용합니다.


3. 핵심 개념·구조

3.1 정밀도 종류와 메모리

타입 바이트 주요 용도
FP32 4B 과학 기술 정밀 계산 (AI 훈련에 거의 미사용)
FP16 2B GPU 학습 최대 정밀도 (AI 기본값)
FP8 1B 메모리 절반 절감, 품질 저하 약 10~20%
FP4 0.5B 극단적 압축 (실험적)
INT8 1B 정수 전용 계산기 고속 동작
INT6 0.75B INT8과 INT4 중간 (GGUF Q6_K 등)
INT4 0.5B 최소 메모리, 품질 손실 주의

⚠️ 주의: FP 실수의 양자화는 "소수점 이하를 버리는" 방식이 아닙니다. 유리한 비트를 선택적으로 날리는 방식으로, 어떤 비트를 제거해야 손실이 최소화되는지가 알고리즘의 핵심입니다.

3.2 양자화 종류 (3가지)

[모델 양자화] ─ 가중치(Weight) 자체를 낮은 정밀도로 저장
                예: W, V, K 파라미터, MLP(FFN) 레이어 파라미터

[활성화 양자화] ─ 모델은 원본 유지 + 인퍼런스 중 내부 연산을 양자화로 실행
                   예: double → float 캐스팅 후 계산

[캐시 양자화] ─ KV 캐시를 낮은 정밀도로 저장·재사용
                 온디바이스 환경에서 메모리(VM) 압박 완화 목적

배포 환경별 조합: - 개발·연구·온디바이스: 모델 + 캐시 양자화 모두 적용 - 상용 서비스 (클라우드 GPU): 양자화 미적용이 대부분

3.3 환각의 구조적 원인

[토큰 생성 루프]
입력 토큰 (t0, t1, ..., tN)
         ↓
다음 토큰 확률 분포 P(tN+1 | t0...tN)
         ↓
확률에 따라 tN+1 선택
         ↓
tN+1이 컨텍스트에 추가 → 반복

[환각 발생 경로]
초기 토큰이 잘못된 방향 → 이후 모든 토큰이
"확률적 일관성" 유지를 위해 같은 방향으로 진행
→ 사실과 다른 내용이 일관되게 이어짐

LLM은 진리·논리·사실이 아닌 확률로 동작합니다. 환각은 모델의 오류가 아니라 이 구조의 자연스러운 결과입니다.


4. 구현 가이드 (Do It Yourself)

시작 전 (Before you begin)

이 섹션을 완료하면 양자화 모델 로드·추론 및 환각 완화 기법을 실제로 구현하고 검증할 수 있습니다.

선수 조건: - Python 3.10+ - pip install transformers bitsandbytes accelerate (GPU 환경) - 또는 pip install llama-cpp-python (CPU 폴백) - (권장) NVIDIA GPU + CUDA 12+ / WSL2 Ubuntu 환경

소요 시간: 약 15~20분.


Step 1 — bitsandbytes NF4 양자화 모델 로드

목표: HuggingFace Transformers + bitsandbytes로 INT4 NF4 양자화 모델을 로드합니다.

다음 코드를 quant_load.py에 작성합니다.

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import torch

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
)
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-3.1-8B-Instruct",
    quantization_config=bnb_config,
    device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B-Instruct")

이 코드는 8B 모델을 FP16(약 16GB) 대비 약 1/4 크기인 4~5GB VRAM으로 로드합니다.

⚠️ 주의: load_in_4bit은 NVIDIA GPU + CUDA 11+ 필요. CPU 전용 환경에서는 Step 4의 llama.cpp GGUF 방식을 사용합니다.

💡 실무 노하우: bnb_4bit_compute_dtype=torch.bfloat16float16보다 NaN 발생이 적습니다. A100/H100 환경을 권장하지만 RTX 30xx/40xx 시리즈에서도 동작합니다.

📚 참고: bitsandbytes 공식 README, HuggingFace Transformers quantization 가이드

확인: nvidia-smi로 VRAM 점유가 약 4~5GB임을 확인합니다.


Step 2 — 추론 실행 및 출력 검증

목표: 양자화 모델로 기본 추론을 실행하고 응답 시간을 확인합니다.

import time

prompt = "Q: 한국의 수도는?\nA:"
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
t0 = time.time()
outputs = model.generate(**inputs, max_new_tokens=50, do_sample=False)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
print(f"추론 시간: {time.time() - t0:.2f}s")

예상 출력:

Q: 한국의 수도는?
A: 한국의 수도는 서울입니다.
추론 시간: 0.8s

확인: 응답이 1~2초 내 반환되고 의미 있는 답변이 출력됩니다.


Step 3 — 환각 완화: 인퍼런스 제어 (Temperature / Top-p)

목표: temperature를 낮춰 더 결정적인 출력을 유도합니다.

# 고온: 창의적이지만 환각 가능성 높음
out_high = model.generate(**inputs, max_new_tokens=100,
                          do_sample=True, temperature=1.2, top_p=0.95)

# 저온: 결정적, 환각 감소 (단 다양성 희생)
out_low  = model.generate(**inputs, max_new_tokens=100,
                          do_sample=True, temperature=0.1, top_p=0.9)

⚠️ 주의: temperature=0 (greedy decoding)이 가장 결정적이나 다양성이 없습니다. 사실 기반 질문에는 0.0~0.3, 창의적 생성에는 0.7~1.0 범위를 사용합니다.

💡 실무 노하우: top_p(nucleus sampling)와 temperature 동시 조정은 효과가 중복됩니다. 한쪽만 강하게 설정하고 다른 쪽은 기본값에 가깝게 유지합니다.

📚 참고: Anthropic Messages API — temperature 파라미터, OpenAI API Reference

확인: 동일 프롬프트에서 temperature 차이에 따라 출력 일관성이 달라짐을 확인합니다.


Step 4 — 환각 완화: RAG (Retrieval-Augmented Generation)

목표: 외부 컨텍스트를 입력 토큰에 주입해 생성 방향을 고정합니다.

# RAG: 정답 컨텍스트를 프롬프트에 포함
context = "서울은 대한민국의 수도이며 약 1000만 명이 거주한다."
rag_prompt = f"컨텍스트: {context}\n\nQ: 한국의 수도는 어디인가?\nA:"
inputs = tokenizer(rag_prompt, return_tensors="pt").to(model.device)
out = model.generate(**inputs, max_new_tokens=60, do_sample=False)
print(tokenizer.decode(out[0], skip_special_tokens=True))

LLM은 직전까지의 모든 입력 토큰에 영향을 받으므로, 컨텍스트를 미리 삽입하면 생성 방향을 유도할 수 있습니다.

💡 실무 노하우: RAG 파이프라인에서 검색 품질이 곧 환각 완화 품질입니다. 벡터 검색 recall을 먼저 측정하고, 불필요한 컨텍스트를 주입하면 오히려 혼동을 줍니다.

📚 참고: LangChain RAG 구현 예시, LlamaIndex RAG 가이드

확인: RAG 없는 경우 대비 더 정확하고 컨텍스트 기반의 답변이 출력됩니다.


Step 5 — llama.cpp GGUF 폴백 (GPU 없을 때)

목표: GPU 없는 CPU 환경에서 GGUF 양자화 모델을 실행합니다.

from llama_cpp import Llama  # pip install llama-cpp-python

llm = Llama(model_path="./llama-3.1-8b-instruct.Q4_K_M.gguf",
            n_ctx=4096, n_gpu_layers=0)
resp = llm.create_chat_completion(
    messages=[{"role": "user", "content": "한국의 수도는?"}]
)
print(resp["choices"][0]["message"]["content"])

GGUF Q4_K_M은 INT4 기반으로 CPU에서 안정적으로 동작하는 표준 포맷입니다 (2026-05 기준, llama.cpp docs).

📚 참고: llama.cpp — CPU 추론 표준. Ollama는 llama.cpp 위의 편의 래퍼입니다.

확인: CPU 추론이 완료되고 의미 있는 답변이 반환됩니다 (속도는 GPU 대비 느림).


Step 6 — 종합 검증 (메모리 + latency + 환각 비교)

목표: 양자화 설정별 메모리·속도·품질 3가지 지표를 측정합니다.

import torch, time

def measure_inference(model, tokenizer, prompt, **gen_kwargs):
    inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
    t0 = time.time()
    out = model.generate(**inputs, **gen_kwargs)
    elapsed = time.time() - t0
    mem_gb = torch.cuda.memory_allocated() / 1e9
    return tokenizer.decode(out[0], skip_special_tokens=True), elapsed, mem_gb

⚠️ 주의: 동일 태스크에서 FP16 베이스라인과 비교해 품질 저하 퍼센트를 반드시 기록합니다. 숫자 없는 "잘 된다" 판단은 근거가 부족합니다.

💡 실무 노하우: 코드 생성·수학 문제는 quantization 손실이 일반 대화보다 크게 나타납니다. 도메인별로 따로 측정합니다.

📚 참고: TruthfulQA 벤치마크 — 환각(사실성) 평가 표준 데이터셋.

확인: 메모리 절감률, latency 변화, 품질 저하 수치 3가지를 모두 기록합니다.


5. 적용 사례 (공신력 오픈소스)

다음은 양자화 및 환각 도메인의 GitHub stars 5K+ 공신력 OSS입니다 (2026-05 기준):

  • bitsandbytes (https://github.com/bitsandbytes-foundation/bitsandbytes) — 4bit/8bit 양자화 PyTorch 라이브러리. HuggingFace Transformers 공식 통합. NF4·FP4 지원.
  • llama.cpp (https://github.com/ggerganov/llama.cpp) — CPU 추론 표준. GGUF 양자화 포맷(Q2_K~Q8_0) 정의 및 구현체. 온디바이스 배포 기준.
  • AutoAWQ (https://github.com/casper-hansen/AutoAWQ) — Activation-aware Weight Quantization 구현. INT4 추론 latency 우수. vLLM 통합 지원.
  • GPTQ (https://github.com/IST-DASLab/gptq) — Post-Training Quantization 원본 알고리즘 구현. PTQ 표준 논문 기반.
  • vLLM (https://github.com/vllm-project/vllm) — 양자화 모델(AWQ/GPTQ/FP8) 고성능 inference serving. PagedAttention 기반 KV 캐시 관리.
  • Ollama (https://github.com/ollama/ollama) — llama.cpp 기반 GGUF 모델 라이브러리. 로컬 LLM 운영 표준 도구.
  • HuggingFace Transformers (https://github.com/huggingface/transformers) — bitsandbytes·GPTQ·AWQ 통합 양자화 API 표준.
  • TruthfulQA (https://github.com/sylinrl/TruthfulQA) — 환각(factuality) 평가 벤치마크. 817개 질문으로 모델 사실성 측정.

💡 실무 노하우: 소규모 로컬 실험은 Ollama/llama.cpp, 학습·프로토타이핑은 HuggingFace Transformers+bitsandbytes, 프로덕션 서빙은 vLLM을 선택합니다. 용도별 도구 분리로 운영 복잡도를 낮춥니다.


6. 핵심 원리

원리 1: 정밀도-품질 비선형 관계

메모리를 절반으로 줄여도(FP16 → FP8) 모델 품질은 절반이 줄지 않습니다. 실증적으로 10~20% 수준의 품질 저하만 발생합니다. 이 비선형 관계가 양자화를 실용적으로 만드는 근거입니다.

LLM 파라미터 분포가 특정 범위에 집중되어 있어, 낮은 정밀도로도 핵심 정보를 보존할 수 있습니다. NF4(Normalized Float 4-bit)는 이 분포 특성을 활용해 정규분포 근사 격자점을 사용하는 방식입니다.

원리 2: 환각의 자기강화(Self-reinforcing) 구조

LLM은 직전까지 생성된 모든 토큰을 컨텍스트로 사용해 다음 토큰을 결정합니다. 초기 토큰이 잘못된 방향을 설정하면, 이후 토큰 생성은 그 방향의 확률적 일관성을 유지하는 쪽으로 진행됩니다. 결과적으로 사실과 무관한 내용이 매끄럽고 일관되게 이어집니다.


7. 변형·확장

환각 완화 전략 3가지

전략 A — 인퍼런스 제어 (Temperature / Top-p)

확률 샘플링 파라미터에 직접 간섭해 생성 방향의 확산을 제어합니다.

  • temperature=0: greedy decoding, 가장 높은 확률의 토큰만 선택
  • top_p=0.8: 누적 확률 80% 이내 토큰만 후보 → 비정상 토큰 차단

적용 시점: 사실 기반 답변, 수치 출력, 분류 작업.

전략 B — 파인튜닝 (fine-tuning, RLHF)

특정 도메인·응답 스타일로 모델을 미세조정해 생성 방향에 강한 편향을 주입합니다.

적용 시점: 특정 도메인(의료·법률·금융 등) 전용 모델, 응답 포맷 고정이 필요할 때.

전략 C — 입력 토큰 제어 (프롬프트 엔지니어링 / RAG)

정확한 사실 컨텍스트를 입력 토큰에 미리 포함시켜 생성 방향을 유도합니다.

💡 실무 노하우: 세 전략은 독립적이 아닙니다. RAG(C) + 낮은 temperature(A)를 조합하면 사실 기반 답변의 정확도가 크게 향상됩니다. 파인튜닝(B)은 비용이 크므로 A+C 조합으로 충분한지 검증 후 고려합니다.


8. 다른 도구·접근과의 비교 (3-way)

항목 FP16 (양자화 없음) INT8 INT4 (NF4/GGUF Q4)
메모리 (7B 기준) 약 14GB 약 7GB 약 3.5~4GB
품질 저하 기준 (0%) 약 5~10% 약 15~25%
추론 속도 기준 GPU: 비슷, CPU: 빠름 GPU: 약간 빠름, CPU: 훨씬 빠름
MPU 지원 불가 가능 가능
권장 환경 클라우드 GPU 서빙 균형 필요 시 온디바이스, 로컬 실험

📚 참고: HuggingFace Quantization 비교 문서 (2026-05 기준, HuggingFace docs)


9. 한계·트레이드오프

  1. 품질 손실 비가역성: 양자화로 제거된 정밀도는 복원 불가합니다. 특히 수치 계산·코딩·수식 추론 태스크에서 INT4 손실이 뚜렷합니다.
  2. 도메인 편차: 일반 언어 태스크에서는 양자화 손실이 작지만, 의료·수학·코드 생성 같은 정밀 도메인에서는 손실이 커질 수 있습니다. 목표 도메인에서 별도 평가가 필요합니다.
  3. 환각 완화의 불완전성: Temperature 제어·RAG·fine-tuning 모두 환각을 줄이지만 완전히 제거하지 못합니다. 고신뢰성 시스템에서는 사후 검증(fact-checking) 레이어가 별도로 필요합니다.

10. 최신 권장 패턴 (2026-05 기준, HuggingFace·llama.cpp docs)

  • NF4 (Normalized Float 4-bit): bitsandbytes bnb_4bit_quant_type="nf4" 기본 권장. 정규분포 근사 격자로 실수 파라미터 분포에 최적화.
  • AWQ (Activation-aware Weight Quantization): INT4 추론 latency 최우수. AutoAWQ + vLLM 조합이 프로덕션 서빙 표준.
  • GGUF Q4_K_M: CPU 추론 표준. llama.cpp/Ollama 기반 온디바이스 배포에 사용.
  • 환각 완화 조합 권장: RAG + temperature=0.1~0.3 + 시스템 프롬프트 제약 조건 3중 조합.

⚠️ 주의: 양자화 포맷·라이브러리 버전은 빠르게 변합니다. 프로덕션 적용 전 해당 라이브러리의 최신 릴리즈 노트를 확인하세요.


11. 메타인지 자기평가

Step 1 — 현재 상태 점검

# GPU 확인
nvidia-smi
# 설치 패키지 확인
pip list | grep -E "bitsandbytes|transformers|llama"

다음 질문에 답해보세요: - INT4와 FP16의 메모리 차이를 구체적인 수치로 설명할 수 있는가? - 환각이 모델의 버그가 아닌 이유를 구조적으로 설명할 수 있는가? - 세 가지 환각 완화 전략의 원리와 적용 시점을 구분할 수 있는가?

Step 2 — 적용 가능성 평가

현재 작업 중인 LLM 프로젝트에서: - GPU VRAM이 부족한가? → 양자화 적용 우선 고려 - 출력 사실성이 중요한가? → RAG + temperature 제어 조합 - 온디바이스(엣지) 배포 필요한가? → INT8/INT4 + MPU 최적화 필수

Step 3 — 점진 적용

  1. bitsandbytes INT8 로드 → 품질 측정 → INT4로 강화 여부 결정
  2. 기존 프롬프트에 RAG 컨텍스트 추가 → 환각 감소 측정
  3. 목표 도메인 벤치마크(TruthfulQA 등)로 품질 검증 → fine-tuning 필요 여부 판단

생성: 2026-05-23 | phase_6_vendor: claude-sonnet-4-6 | domain: ai_engineering

난이도
에피소드
질문
카드를 로딩 중...
답변

클릭하거나 Space를 눌러 뒤집기

0 / 0
학습 진도 0%
이동   Space 뒤집기   R 셔플